package com.linkoog.devtools.maven.dependency_folding;

import com.intellij.codeInsight.folding.impl.EditorFoldingInfo;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.editor.FoldingModel;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

public class CollapseAllAction extends AnAction {

    @Override
    public void update(AnActionEvent e) {
        // enable if there is at least 1 custom folding region
        List<FoldRegion> foldingRegions = getFoldingRegions(e);
        e.getPresentation().setEnabledAndVisible(foldingRegions != null && !foldingRegions.isEmpty());
    }

    @Override
    public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.BGT;
    }

    @Override
    public void actionPerformed(AnActionEvent e) {
        Editor editor = e.getData(LangDataKeys.EDITOR);
        if (editor == null) return;

        FoldingModel foldingModel = editor.getFoldingModel();
        foldingModel.runBatchFoldingOperation(()->{
            // collapse all folding regions
            List<FoldRegion> foldingRegions = getFoldingRegions(e);
            if (foldingRegions == null) return;

            for (FoldRegion region : foldingRegions) {
                region.setExpanded(false);
            }

        }, true, true);
    }

    /**
     * Get the folding regions that are marked as custom
     */
    private List<FoldRegion> getFoldingRegions(AnActionEvent e) {
        Editor editor = e.getData(LangDataKeys.EDITOR);
        if (editor != null) {
            FoldingModel foldingModel = editor.getFoldingModel();
            FoldRegion[] allFoldRegions = foldingModel.getAllFoldRegions();
            List<FoldRegion> customFoldRegions = new ArrayList<>();
            for (FoldRegion region : allFoldRegions) {
                EditorFoldingInfo editorFoldingInfo = EditorFoldingInfo.get(region.getEditor());
                PsiElement psiElement = editorFoldingInfo.getPsiElement(region);
                if (psiElement == null) continue;

                Boolean foldFlag = psiElement.getUserData(DependencyFoldsBuilder.USER_DATA);
                if (Boolean.TRUE.equals(foldFlag)) {
                    customFoldRegions.add(region);
                }
            }
            return customFoldRegions;
        }
        return null;
    }
}
